
#include "ConwayLifeGame.h"

#include "kkgui_app.h"
#include "kkgui_base.h"
#include "kkgui_key.h"

/**********************康威生命游戏************************/

#define KWG_WITH 88
#define KWG_HIGH 62

const uint8_t KWG_cdata[62 + 8][11 + 1] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x02,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x20,0x20,
0x00,0x0C,0x00,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0xF0,0x10,0x02,0x0C,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x03,0x58,0x21,0x00,0x00,0x00,0x80,0x61,0x00,0x18,0x00,
0x00,0x03,0x5C,0x22,0x02,0x00,0x00,0x80,0x61,0x00,0x18,0x00,0x00,0x00,0x58,0x81,0x02,0x00,0x00,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,
0x00,0x02,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x80,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0x00,0x00,0x00,0x00,0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x40,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0xC0,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x20,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0xC0,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x40,0x02,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8E,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* (96 X 70 )*/


};

uint8_t KWG_data[62 + 8][11 + 1];

uint8_t KWG_ldata[62 + 8][11 + 1] = {0};

uint8_t KWG_GetPoint(int x, int y)
{
    if(x < -1 || y < -1 || x > KWG_WITH + 8|| y > KWG_HIGH + 8)
        return 0;
        
    // if(x == -1)
	// 	return  !(y%3);
    // else if(x == KWG_WITH + 8)
	// 	return  !(2-(y%3));
    // else if(y == -1)
	// 	return  !(x%3);
    // else if(y == KWG_HIGH + 8)
	// 	return  !(2-(x%3));

    int x_byte = x / 8;
    uint8_t x_bit = x % 8;

    if(KWG_ldata[y][x_byte] & 1 << x_bit)
        return 1;
    else
        return 0;
}   

void KWG_SetNewPoint(int x, int y, uint8_t data)
{
    if(x < 0 || y < 0 || x >= KWG_WITH + 8 || y >= KWG_HIGH + 8)
        return;

    int x_byte = x / 8;
    uint8_t x_bit = x % 8;

    if(data)
    {
        KWG_data[y][x_byte] = KWG_data[y][x_byte] | (1 << x_bit);
    }
    else
    {
        KWG_data[y][x_byte] = KWG_data[y][x_byte] & (~(1 << x_bit));
    }
    
}

uint8_t KWG_GetNearNum(int x, int y)
{
    uint8_t num = 0;
    num = num + KWG_GetPoint(x-1, y-1);
    num = num + KWG_GetPoint(x-1, y  );
    num = num + KWG_GetPoint(x-1, y+1);
    num = num + KWG_GetPoint(x  , y-1);
    num = num + KWG_GetPoint(x  , y+1);
    num = num + KWG_GetPoint(x+1, y-1);
    num = num + KWG_GetPoint(x+1, y  );
    num = num + KWG_GetPoint(x+1, y+1);

    return num;
}

uint8_t KWG_Action(void)
{
    int retx, rety;
    uint8_t kn_point;
    uint8_t kn_near_num;
    memset(KWG_data , 0, sizeof(KWG_data));
    for(rety = 0 ; rety < KWG_HIGH + 8 ; rety ++)
    {
        for(retx = 0 ; retx < KWG_WITH + 8 ; retx ++)
        {
            kn_point = KWG_GetPoint(retx, rety);
            kn_near_num = KWG_GetNearNum(retx, rety);
            if(kn_point && kn_near_num != 3 && kn_near_num != 2)
            {
                KWG_SetNewPoint(retx, rety, 0);
            }
            else if(kn_point && (kn_near_num == 3 || kn_near_num == 2))
            {
                KWG_SetNewPoint(retx, rety, 1);
            }
            else if(!kn_point && kn_near_num == 3)
            {
                KWG_SetNewPoint(retx, rety, 1);
            }
            else
            {
                KWG_SetNewPoint(retx, rety, 0);
            }
        }
    }
    memcpy(KWG_ldata, KWG_data, sizeof(KWG_data));
}

void KWG_dis(void)
{    
    int retx, rety;
    for(rety = 0; rety < KWG_HIGH ; rety ++)
    {
        for(retx = 0; retx < KWG_WITH ; retx ++)
        {
            uiDrawPoint(retx + 1, rety + 1, KWG_GetPoint(retx + 4, rety + 4));
            // if(KWG_GetPoint(retx + 4, rety + 4))
            // {
            //     uiDrawBlock()
            //     printf("O");
            // }
            // else
            // {
            //     printf(" ");
            // }
        }
    }
}

void KWG_Loop(kkui_menu_event_e event, char* tab_name, void* param)
{    
    static uint8_t KWG_runflag = 0;
    if(event == ENTER_TAG)
    {
        uiDisClear(0);
    }
    if(LOOP_RUN == event)
    {
        KWG_dis();
        if(KWG_runflag)
            KWG_Action();
        if(uiKeyGetValue(UI_KEY_ENTER_ID) == DOWN)
            KWG_runflag = !KWG_runflag;
        if(uiKeyGetValue(UI_KEY_SET_ID) == DOWN)
            memcpy(KWG_ldata, KWG_cdata, sizeof(KWG_data));
        if(uiKeyGetValue(UI_KEY_BACK_ID) == DOWN)
            uiBackAppLoop();
    }
}
